package com.xtx.air.bo.user.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import javax.mail.internet.MimeMessage;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.shiro.crypto.RandomNumberGenerator;
import org.apache.shiro.crypto.SecureRandomNumberGenerator;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.util.ByteSource;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;

import com.xtx.air.bo.user.IUserBO;
import com.xtx.air.dao.feature.IFeatureDAO;
import com.xtx.air.dao.user.IUserDAO;
import com.xtx.air.dataobject.UserDO;
import com.xtx.exception.BOException;
import com.xtx.util.RandomUtil;
import com.xtx.util.StringUtil;

/**
 * User: hanyi
 * Date: 12-2-9
 * Time: 下午8:48
 */
public class UserBOImpl implements IUserBO{
    private Log logger = LogFactory.getLog(this.getClass());
    public IUserDAO userDAO;
    public IFeatureDAO featureDAO;
    public JavaMailSender mailSender;


    public void setMailSender(JavaMailSender mailSender) {
        this.mailSender = mailSender;
    }

    public void setUserDAO(IUserDAO userDAO) {
        this.userDAO = userDAO;
    }

    public void setFeatureDAO(IFeatureDAO featureDAO) {
        this.featureDAO = featureDAO;
    }

    @Override
    public List<UserDO> findUser(UserDO user) {
        try{
            List<UserDO> list =  userDAO.findUser(user);
            if(list != null){
                for(UserDO userDO :list){
                    List<String> roles = userDAO.findUserRoleById(userDO.getId());
                    if(roles != null && !roles.isEmpty()){
                        //目前一个用户只支持一个角色
                        userDO.setRole(roles.get(0));
                    }
                }
            }
            return list;
        }catch (Exception e){
            logger.error("查询用户失败",e);
            return Collections.emptyList();
        }
    }

    @Override
    public void updateRoleUserRef(UserDO user) {
        try{
            userDAO.updateRoleUserRef(user);
        }catch (Exception e){
            logger.error("更新用户角色失败",e);
            throw new BOException(e);
        }
    }

    @Override
    public void resetUserPass(Long userId) {
        if(userId == null){
            throw new IllegalArgumentException("userId is null");
        }
        String newPass = RandomUtil.getRandomString(8);
        RandomNumberGenerator rng = new SecureRandomNumberGenerator();
        ByteSource salt = rng.nextBytes();
        String hashedPasswordBase64 = new Sha256Hash(newPass, salt, 1024).toBase64();
        UserDO user = new UserDO();
        user.setPassword(hashedPasswordBase64);
        user.setSalt(salt.toBase64());
        user.setId(userId);
        try{
            UserDO currentUser = userDAO.getUserById(userId);
            if (currentUser != null) {
                userDAO.updateUser(user);
                MimeMessage mimeMessage = buildMessage(currentUser.getEmail(),newPass);
                mailSender.send(mimeMessage);
            }else {
                throw new BOException("当前用户不存在");
            }
        }catch (Exception e){
            logger.error("重置密码发生异常",e);
            throw new BOException("重置密码发生异常",e);
        }
    }

    private MimeMessage buildMessage(String email,String password){
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        try {
            MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "GBK");
            // 发件人地址及名称
            mimeMessageHelper.setFrom("eightplayss@163.com", "行天下旅游网");
            // 邮件接收者
            mimeMessageHelper.setTo(new String[]{email});
            // 邮件标题
            mimeMessageHelper.setSubject("行天下机票平台-密码重置");
            mimeMessageHelper.setText("重置后的密码为："+password, true);
            // 邮件优先级
            mimeMessageHelper.setPriority(1);
        } catch (Exception e) {
            throw new BOException(e);
        }
        return mimeMessage;
    }

    @Override
    public void updateUserInfo(UserDO user) {
        try{
            userDAO.updateUser(user);
        }catch (Exception e){
            logger.error("更新用户信息失败",e);
            throw new BOException(e);
        }
    }

    @Override
    public UserDO getUserById(Long userId) {
        try{
            return userDAO.getUserById(userId);
        }catch (Exception e){
            logger.error("查询用户信息失败",e);
            throw new BOException(e);
        }
    }

    @Override
    public void addUser(UserDO user) {
        if (user == null) {
            throw new IllegalArgumentException("用户不能为空");
        } else if (StringUtil.isEmpty(user.getEmail())) {
            throw new IllegalArgumentException("邮箱不能为空");
        } else if (StringUtil.isEmpty(user.getPassword())) {
            throw new IllegalArgumentException("密码不能为空");
        }
        try {
            UserDO userDO = userDAO.getUserByEmail(user.getEmail());
            if (userDO != null) {
                throw new BOException("当前用户已经存在，不能注册");
            }
            RandomNumberGenerator rng = new SecureRandomNumberGenerator();
            ByteSource salt = rng.nextBytes();
            String hashedPasswordBase64 = new Sha256Hash(user.getPassword(), salt, 1024).toBase64();
            user.setPassword(hashedPasswordBase64);
            user.setSalt(salt.toBase64());
            userDAO.addUser(user);
        } catch (Exception e) {
            logger.error("新增用户出错", e);
            throw new BOException("注册发生未知异常");
        }
    }

    @Override
    public UserDO getUserByEmail(String email) {
        try{
            return userDAO.getUserByEmail(email);
        }catch (Exception e){
            logger.error("根据email查询用户出错,email="+email,e);
            return null;
        }
    }

    @Override
    public List<String> findUserPermission(String email) {
        if (email == null) {
            throw new IllegalArgumentException("email不能为空");
        }
        try {
            UserDO user = userDAO.getUserByEmail(email);
            if (user != null) {
                List<String> roles = userDAO.findUserRoleById(user.getId());
                List<String> permissions = new ArrayList<String>();
                for (String role : roles) {
                    permissions.addAll(featureDAO.findOperatorPermissionByRole(role));
                }
                return permissions;
            } else {
                return Collections.emptyList();
            }
        } catch (Exception e) {
            logger.error("查询用户权限失败,email=" + email, e);
            return Collections.emptyList();
        }
    }
}
